package pl.lsierant.j2me.bipacz.persistent;

import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Vector;

import pl.lsierant.j2me.bipacz.log.Logger;

public class SerializationHelper {
    private static final Logger logger = new Logger("SerializationHelper");

    private final IPersistent persistentObject;
    private final DataOutputStream out;
    private final int versionId;

    public SerializationHelper(DataOutputStream out, IPersistent persistentObject, int versionId)
            throws IOException {
        this.out = out;
        this.persistentObject = persistentObject;
        this.versionId = versionId;
        initialize();
    }

    private void initialize() throws IOException {
        logger.log("initialize: type = " + persistentObject.getPersistentObjectType());
        addType(persistentObject.getPersistentObjectType());
        out.writeInt(versionId);
    }

    private void addType(int persistentObjectType) throws IOException {
        logger.log("addType: type = ", persistentObjectType);
        out.writeInt(persistentObjectType);
    }

    public SerializationHelper addField(String value) throws IOException {
        logger.log("addStringField: value = ", value);

        addType(PersistentObjectType.STRING);
        out.writeUTF(value);
        return this;
    }

    public SerializationHelper addField(IPersistent persistent) throws IOException {
        logger.log("addPersistentField: type = ", persistent.getPersistentObjectType());
        persistent.serialize(out);
        return this;
    }

    public SerializationHelper addObjectField(Object value) throws IOException {
        logger.log("addObjectField: ", value);
        if (value == null) {
            throw new IllegalArgumentException("value == null");
        }
        if (value instanceof Integer) {
            addField(((Integer) value).intValue());
        } else if (value instanceof String) {
            addField((String) value);
        } else if (value instanceof IPersistent) {
            addField((IPersistent) value);
        } else {
            throw new PersistentException("Invalid object: " + value.getClass().getName());
        }
        return this;
    }

    public SerializationHelper addVector(Vector vector) throws IOException {
        logger.log("addVector: value = ", vector);

        if (vector == null) {
            throw new IllegalArgumentException("vector == null");
        }
        addType(PersistentObjectType.VECTOR);
        logger.log("addVector: addInt size = ", vector.size());
        out.writeInt(vector.size());
        for (int i = 0; i < vector.size(); i++) {
            addObjectField(vector.elementAt(i));
        }
        return this;
    }

    public SerializationHelper addField(int value) throws IOException {
        logger.log("addIntField: value = ", value);
        addType(PersistentObjectType.INTEGER);
        out.writeInt(value);
        return this;
    }

    public SerializationHelper addField(long value) throws IOException {
        logger.log("addLongField: value = ", value);
        addType(PersistentObjectType.LONG);
        out.writeLong(value);
        return this;
    }
}
